<!DOCTYPE html>
<html lang='en'>

<head>
    <meta charset='UTF-8'>
    <meta http-equiv='X-UA-Compatible' content='IE=edge'>
    <meta name='viewport' content='width=device-width, initial-scale=1.0'>
    <title>Document</title>
    <style>
        body {
            margin: 30px;
        }

        svg {
            display: block;
        }

        polygon {
            fill: #41b883;
        }

        circle {
            fill: transparent;
            stroke: #35495e;
        }

        input[type="range"] {
            display: block;
            width: 100%;
            margin-bottom: 15px;
        }
    </style>
    <script src='./vue.global.js'></script>
    <script src='./gsap.min.js'></script>
</head>

<body>
    <div id="demo">
        <svg width="200" height="200">
            <polygon :points="points"></polygon>
            <circle cx="100" cy="100" r="90"></circle>
        </svg>
        <label>Sides: {{ sides }}</label>
        <input type="range" min="3" max="500" v-model.number="sides" />
        <label>Minimum Radius: {{ minRadius }}%</label>
        <input type="range" min="0" max="90" v-model.number="minRadius" />
        <label>Update Interval: {{ updateInterval }} milliseconds</label>
        <input type="range" min="10" max="2000" v-model.number="updateInterval" />
    </div>
    <script>
        const defaultSides = 10;
        const stats = Array.apply(null, { length: defaultSides }).map(() => 100);

        const Demo = {
            data() {
                return {
                    stats: stats,
                    points: generatePoints(stats),
                    sides: defaultSides,
                    minRadius: 50,
                    interval: null,
                    updateInterval: 500
                };
            },
            watch: {
                sides(newSides, oldSides) {
                    var sidesDifference = newSides - oldSides;
                    if (sidesDifference > 0) {
                        for (var i = 1; i <= sidesDifference; i++) {
                            this.stats.push(this.newRandomValue());
                        }
                    } else {
                        var absoluteSidesDifference = Math.abs(sidesDifference);
                        for (var i = 1; i <= absoluteSidesDifference; i++) {
                            this.stats.shift();
                        }
                    }
                },
                stats(newStats) {
                    gsap.to(this.$data, this.updateInterval / 1000, {
                        points: generatePoints(newStats)
                    });
                },
                updateInterval() {
                    this.resetInterval();
                }
            },
            mounted() {
                this.resetInterval();
            },
            methods: {
                randomizeStats() {
                    var vm = this;
                    this.stats = this.stats.map(() => vm.newRandomValue());
                },
                newRandomValue() {
                    return Math.ceil(this.minRadius + Math.random() * (100 - this.minRadius));
                },
                resetInterval() {
                    var vm = this;
                    clearInterval(this.interval);
                    this.randomizeStats();
                    this.interval = setInterval(() => {
                        vm.randomizeStats();
                    }, this.updateInterval);
                }
            }
        };

        Vue.createApp(Demo).mount("#demo");

        function valueToPoint(value, index, total) {
            var x = 0;
            var y = -value * 0.9;
            var angle = ((Math.PI * 2) / total) * index;
            var cos = Math.cos(angle);
            var sin = Math.sin(angle);
            var tx = x * cos - y * sin + 100;
            var ty = x * sin + y * cos + 100;
            return { x: tx, y: ty };
        }

        function generatePoints(stats) {
            var total = stats.length;
            return stats
                .map(function (stat, index) {
                    var point = valueToPoint(stat, index, total);
                    return point.x + "," + point.y;
                })
                .join(" ");
        }
    </script>
</body>

</html>